package com.zonerobotics.tutorial.btcontrol;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;

import com.zonerobotics.zBotAPI.Listeners.IBotListener;
import com.zonerobotics.zBotAPI.ZBot.*;



import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

/**
 * This class is simply to setup your poll service with the required 
 * input and output streams. It is an example of how the api can be 
 * used with a bluetooth device to talk with a zbot. Once this is successful 
 * you can get the bot object to be able to control it or read its vars.
 * After that this has no use.
 * 
 * This is android specific code whereas the api is pure java
 * @author Michael McCarty
 * Feb 3, 2013
 */
public class InitBTComm {
	
		private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
		private final BluetoothSocket mmSocket;
	    private final BluetoothDevice mmDevice;
	    // setup bluetooth, make sure its on etc
	    private BluetoothAdapter mBtAdapter;
	    
	    // Debugging
	    private static final String TAG = "Init Bot Bluetooth";
	    private static final boolean D = true;

	    // our streams
	    private OutputStream stmOutput = null;
	    private InputStream stmInput = null;

	    IZBot zBot = null;
	    
	    /**
	     * this will setup your bot and your polling service 
	     * so that they are both running based off the mac addr
	     * of a bluetooth device you have paired with
	     * @param devAddr
	     * mac address of device to pair with
	     */
	    public InitBTComm(String devAddr, IBotListener ibl)
	    {
	    	mBtAdapter = BluetoothAdapter.getDefaultAdapter();
	    	Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
	    	BluetoothDevice Device = null;
            for (BluetoothDevice device : pairedDevices) {
            	if(device.getAddress().equalsIgnoreCase(devAddr))
            	{
            		Device = device;
            		break;
            	}
            }
            // todo see if we found it before we assume ? 
            mmDevice = Device;

	        // Use a temporary object that is later assigned to mmSocket,
	        // because mmSocket is final
	        BluetoothSocket tmp = null;
	        
	        // Get a BluetoothSocket to connect with the given BluetoothDevice
	        //try {
	            // MY_UUID is the app's UUID string, also used by the server code
	            // tmp = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
	        	Method m;
				try {
					m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
					try {
						tmp = (BluetoothSocket) m.invoke(mmDevice, 1);
					} catch (IllegalArgumentException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					} catch (IllegalAccessException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					} catch (InvocationTargetException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					}
					
				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				

	            
	        //} catch (IOException e) 
	        //{ 
	        //	if(D) Log.e(TAG, "++ FAIL1 ++");
	        	//return;
	        //}
	        mmSocket = tmp;

	        // Cancel discovery because it will slow down the connection
	    	mBtAdapter.cancelDiscovery();

	        try {
	        	mmSocket.connect();
				stmOutput = mmSocket.getOutputStream();
				stmInput = mmSocket.getInputStream();
				// we have the streams now time to setup our bot and poll

				// create new bot this takes care of everything
				zBot = new com.zonerobotics.zBotAPI.ZBot.ZBot( stmInput, stmOutput );
				zBot.setBotEventListener(ibl);
				
				
				
			} catch (Exception e) 
	        { 
				 try {
					mmSocket.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				 ibl.onLogMessage("Failed to close socket: " + e.getMessage());
	        	if(D) Log.e(TAG, ":Failed to close socket: " + e.getMessage()); 
	        	return;
	        }
	        
	 
	    }
}
